use crate::db::Database;
use crate::handlers;
use axum::{
    routing::{get, post, delete},
    Router,
};
use std::net::SocketAddr;
use std::sync::Arc;
use tower_http::cors::CorsLayer;
use tracing::info;

pub struct ApiServer {
    addr: SocketAddr,
    db: Arc<Database>,
}

impl ApiServer {
    pub async fn new(addr: SocketAddr, database_url: &str) -> anyhow::Result<Self> {
        let db = Database::new(database_url).await?;
        
        Ok(Self {
            addr,
            db: Arc::new(db),
        })
    }

    pub async fn serve(self) -> anyhow::Result<()> {
        let pool = Arc::new(self.db.pool().clone());

        let app = Router::new()
            // Auth routes
            .route("/api/auth/login", post(handlers::login))
            
            // User routes
            .route("/api/users", get(handlers::list_users))
            .route("/api/users", post(handlers::create_user))
            .route("/api/users/:id", get(handlers::get_user))
            .route("/api/users/:id", delete(handlers::delete_user))
            
            // Traffic routes
            .route("/api/traffic/stats", get(handlers::get_traffic_stats))
            
            // Server routes
            .route("/api/server/status", get(handlers::get_server_status))
            .route("/api/server/start", post(handlers::start_server))
            .route("/api/server/stop", post(handlers::stop_server))
            
            .layer(CorsLayer::permissive())
            .with_state(pool);

        info!("API server listening on {}", self.addr);

        let listener = tokio::net::TcpListener::bind(self.addr).await?;
        axum::serve(listener, app).await?;

        Ok(())
    }
}
